<template>
  <div class="data-table-container" :class="moduleClass">
    <search ref="search" :tb-columns="tbColumns" :module-info="moduleInfo" />
    <slot name="top" />
    <toolbar v-if="toolbarBtns!==null&&showToolbar!==0" :toolbar-btns="toolbarBtns" :right-toolbar-span="rightToolbarSpan" :custom-toolbar-btns="customToolbarBtns" :mode="mode" :select-custom-toolbar="selectCustomToolbar" :tb-columns="tbColumns" :module-info="moduleInfo" :set-column-enabled="setColumnEnabled">
      <template slot="toolbarLeft-slotLeft">
        <slot name="toolbarLeft-slotLeft" />
      </template>
      <template slot="toolbarLeft-slotRight">
        <slot name="toolbarLeft-slotRight" />
      </template>
    </toolbar>
    <el-table ref="listpageDataTable" :stripe="stripeTable" :data="pageInfo.list" :default-sort="defaultSort" :empty-text="emptyText" border @cell-click="handleCellClick" @sort-change="handleSortChange" @selection-change="handleSelectChange">
      <template v-for="(column, key) in tbColumns">
        <template v-if="column.enabled===true">
          <el-table-column
            v-if="column.checkbox"
            :key="key"
            align="center"
            type="selection"
            width="45"
            :class-name="'column_checkbox'"
            :selectable="selectable"
          />
          <el-table-column
            v-else-if="column.field==='index'"
            :key="key"
            align="center"
            type="index"
            :label="column.title"
            width="45"
            :class-name="'column_index'"
          >
            <template slot-scope="scope">
              <span>{{ (pageInfo.pageNum - 1) * pageInfo.pageSize + scope.$index + 1 }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="column.field==='column_operate'"
            :key="key"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :class-name="'column_operate'"
          >
            <template slot="header" slot-scope="scope">
              <el-link v-for="(btn, btnKey) in tbheaderBtns" :id="scope.index" :key="btnKey" :disabled="innerTableBtnDisabled" @click="btn.cloumHeaderBtnClick(btn)">
                <svg-icon v-if="btn.btnIcon.indexOf('.svg')!==-1" :icon-class="btn.btnIcon.substring(0,btn.btnIcon.indexOf('.svg'))" />
                <i v-else :class="'el-icon-'+btn.btnIcon" />
                {{ btn.btnName }}
              </el-link>
              <span v-if="tbheaderBtns.length===0" v-html="column.title" />
            </template>
            <template slot-scope="scope">
              <template v-for="(btn, btnKey) in operateColumnBtns">
                <el-link v-if="btn.btnShow?scope.row[btn.btnShow.field]===btn.btnShow.value:true" :key="btnKey" :title="btn.btnName" @click="btn.btnClick(scope.row,column,scope.row[column.field],key)">
                  <svg-icon v-if="btn.btnIcon.indexOf('.svg')!==-1" :icon-class="btn.btnIcon.substring(0,btn.btnIcon.indexOf('.svg'))" />
                  <i v-else-if="btn.btnIcon!=='' && btn.btnIcon.indexOf('.svg')===-1" :class="'el-icon-'+btn.btnIcon" />
                  <span v-else>{{ btn.btnName }}</span>
                </el-link>
              </template>
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="column.funcFormatter"
            :key="key"
            :prop="column.field"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :min-width="!column.width?'150px':''"
            :sortable="column.sortable===true?'custom':false"
            :show-overflow-tooltip="true"
            :class-name="column.className?(column.className+(' column_'+column.field)):('column_'+column.field)"
          >
            <template slot-scope="scope">
              <RenderColumn :column="column" :row="scope.row" :index="key" />
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="column.propFormatter.indexOf('component：')!=-1"
            :key="key"
            :prop="column.field"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :min-width="!column.width?'150px':''"
            :sortable="column.sortable===true?'custom':false"
            :class-name="column.className?(column.className+(' column_'+column.field)):('column_'+column.field)"
          >
            <template slot-scope="scope">
              <components :is="componentColumn" :column="column" :row="scope.row" :index="key" />
            </template>
          </el-table-column>

          <el-table-column
            v-else-if="column.propFormatter==='currency1' || column.propFormatter==='currency2' "
            :key="key"
            :prop="column.field"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :min-width="!column.width?'150px':''"
            :sortable="column.sortable===true?'custom':false"
            :class-name="column.className?(column.className +(' column_'+column.field)+ (isCellClick?' content-column':'')):(isCellClick?'content-column':'')+(' column_'+column.field)"
          >
            <template slot-scope="scope">
              <template v-if="column.propFormatter==='currency1'">{{ scope.row[column.field] | currency }}</template>
              <template v-else>￥{{ Number(scope.row[column.field]).toFixed(2) }}</template>
            </template>
          </el-table-column>
          <el-table-column
            v-else-if="column.propType==='String'&&!column.elementFormatter&&!column.propFormatter"
            :key="key"
            :prop="column.field"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :min-width="!column.width?'150px':''"
            :sortable="column.sortable===true?'custom':false"
            :show-overflow-tooltip="true"
            :class-name="column.className?(column.className +(' column_'+column.field)+ (isCellClick?' content-column':'')):(isCellClick?'content-column':'')+(' column_'+column.field)"
          >
            <template slot-scope="scope">
              <template v-if="scope.row[column.field]&&scope.row[column.field].includes&&scope.row[column.field].includes('enMode')">
                <div class="encrypted" @click.stop="decryptData(scope.row,column.field)"><span>●●●●●●</span><i class="el-icon-view" /></div>
              </template>
              <template v-else>
                {{ scope.row[column.field] }}
              </template>
            </template>
          </el-table-column>
          <el-table-column
            v-else
            :key="key"
            :prop="column.field"
            :label="column.title"
            :align="column.align"
            :width="column.width"
            :min-width="!column.width?'150px':''"
            :sortable="column.sortable===true?'custom':false"
            :show-overflow-tooltip="true"
            :formatter="(column.elementFormatter||column.propFormatter)?elementValueFormatter:null"
            :class-name="column.className?(column.className +(' column_'+column.field)+ (isCellClick?' content-column':'')):(isCellClick?'content-column':'')+(' column_'+column.field)"
          />
        </template>
      </template>
    </el-table>

    <div v-if="pageInfo.total>0 && mode !='inner'" class="el-pagination-container">
      <el-pagination
        :current-page="pageInfo.pageNum"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pageInfo.pageSize"
        :total="pageInfo.total"
        :hide-on-single-page="false"
        layout="total, sizes, prev, pager, next, jumper"
        prev-text="上一页"
        next-text="下一页"
        @size-change="handlePageSizeChange"
        @current-change="handlePageNumChange"
      />
    </div>

    <ResPermission v-if="showResPermission" />

    <!-- 业务模块列表页面扩展插槽 -->
    <slot />
    <DoingDialog />
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import RenderColumn from './RenderColumn'
import ResPermission from './ResPermission'
import Toolbar from './Toolbar'
import Search from './Search'
import qs from 'qs'
import { generateTitle } from '@/global/utils/i18n'

const moment = require('moment')
const PAGE_INFO = { pageSize: 10, total: 0, pageNum: 1 }

export default {
    name: 'DataTable',
    components: {
        Toolbar, Search, RenderColumn, ResPermission
    },
    props: {
        moduleInfo: { type: Object, default: function() { return {} } }, // 模块映射配置信息，包含api接口地址等信息
        tbColumns: { type: Array, default: function() { return [] } }, // 列定义
        toolbarBtns: { type: Array, default: function() { return [] } }, // 操作按钮
        showToolbar: { type: Number, default: 1 }, // 是否显示右上操作按钮
        rightToolbarSpan: { type: Number, default: function() { return 12 } }, // 右上操作按钮组列格栅数，共24列
        customToolbarBtns: { type: Array, default: function() { return [] } }, // 自定义列表左上角toobar按钮
        customToolbarBtnsClick: { type: Function, default: null }, // 自定义列表左上角toobar按钮点击事件
        onListDataBeforeLoad: { type: Function, default: function() {} }, // 列表数据加载前事件
        onListDataLoaded: { type: Function, default: function() {} }, // 列表数据加载后事件
        onDeleteSuccessed: { type: Function, default: function() {} }, // 列表数据删除成功事件
        onSelectedRowsChange: { type: Function, default: function() {} }, // 选择列表数据事件
        onCellClick: { type: Function, default: null }, // 列表单元格单击事件
        listdata: { type: Array, default: function() { return [] } }, // 预加载列表数据
        mode: { type: String, default: 'listpage' }, // 列表呈现模式：listpage=普通列表，inner=表单内嵌子表
        maxSelectRow: { type: Number, default: null }, // 最大允许选择多少行
        isCellClick: { type: Boolean, default: true }, // 是否触发单元格单击事件
        cellSelectionStatus: { type: Function, default: null }// 控制行多选框是否可选择
    },
    data() {
        return {
            loading: false,
            loadingMast: null,
            emptyText: '正在加载..',
            pageInfo: JSON.parse(JSON.stringify(PAGE_INFO)),
            defaultSort: {},
            selectedRows: [],
            searchAndOr: '',
            searchMap: {},
            showResPermission: false,
            customBtnVal: null,
            moduleClass: '',
            stripeTable: this.$store.state.settings.stripeTable,
            innerTableBtnDisabled: false,
            componentColumn: {
                type: Object,
                required: true,
                default() {
                    return { }
                }
            }
        }
    },
    computed: {
        operateColumnBtns() {
            return this.toolbarBtns.filter(item => {
                if (item.btnType === 'column' && item.btnPermission) return true
            })
        },
        tbheaderBtns() {
            return this.toolbarBtns.filter(item => {
                if (item.btnType === 'tbheader' && item.btnPermission) return true
            })
        },
        ...mapGetters([
            'loginUser'
        ])
    },
    watch: {
        moduleInfo: {
            handler: function(newValue, oldValue) {
                this.loadListdata()
            },
            deep: true
        },
        tbColumns: {
            handler() {
                this.initTbColumns()
                this.$forceUpdate()
            },
            deep: true
        },
        toolbarBtns: {
            handler() {
                this.checkBtnPermission()
            },
            deep: true
        }
    },
    created() {
        if (this.moduleInfo.moduleCode) {
            this.moduleClass = this.moduleInfo.moduleCode
        } else if (this.moduleInfo.listDataUrl.substr(0, 1) === '/') {
            this.moduleClass = this.moduleInfo.listDataUrl.split('/')[2]
        } else {
            this.moduleClass = this.moduleInfo.listDataUrl.split('/')[1]
        }

        this.initTbColumns()

        if ((typeof this.moduleInfo.listDefaultOrderBy !== 'undefined') && this.moduleInfo.listDefaultOrderBy !== null) {
            const orderBy = this.moduleInfo.listDefaultOrderBy.split(',')[0].replace(' asc', ' ascending').replace(' desc', ' descending')
            this.defaultSort.prop = orderBy.split(' ')[0]
            this.defaultSort.order = orderBy.split(' ')[1]
        }

        this.checkBtnPermission()

        this.$bus.on('refreshListData', this.refreshListData)
    },
    beforeDestroy() {
        this.$bus.off('refreshListData', this.refreshListData)
    },
    mounted() {
        if (this.$store.state.tagsView.visitedViews && this.moduleInfo) {
            this.$store.state.tagsView.visitedViews.forEach(v => {
                if (v.fullPath === this.$route.fullPath) {
                    if (v.pageInfo && (!v.moduleCode || v.moduleCode === this.moduleInfo.moduleCode)) {
                        if (v.listDataUrl === this.moduleInfo.listDataUrl) {
                            this.pageInfo = v.pageInfo
                        } else {
                            this.moduleInfo.disableCache = true
                        }
                    }

                    if (!v.moduleCode) v.moduleCode = this.moduleInfo.moduleCode
                }
            })
        }

        this.loadListdata()
    },
    methods: {
        checkBtnPermission() {
            const _this = this
            const checkedPermission = {}
            this.toolbarBtns.forEach(async(btn) => {
                if (_this.mode === 'design') {
                    btn.btnPermission = true
                } else {
                    let pcode = ''
                    if (btn.btnType === 'column') {
                        pcode = 'COLUMN_BTN$' + btn.btnPermission
                    } else {
                        pcode = 'TOOLBAR_BTN$' + btn.btnPermission
                    }

                    if (checkedPermission[pcode]) {
                        btn.btnPermission = checkedPermission[pcode]
                    } else {
                        const hasPermission = await this.$store.dispatch('user/hasPermission', { 'href': _this.$route.meta.href, 'pcode': pcode })
                        btn.btnPermission = hasPermission
                    }

                    if (btn.btnPermission === true) {
                        if (typeof btn.btnClick === 'string') {
                            const btnClick = btn.btnClick.split('(')[0]
                            if (_this[btnClick]) {
                                btn.btnClick = _this[btnClick]
                            } else if (_this.$vnode.context[btnClick]) {
                                btn.btnClick = _this.$vnode.context[btnClick]
                            }
                        }
                    }
                }
            })
        },
        initTbColumns() {
            this.tbColumns.forEach(column => {
                if (column.enabled === undefined) column.enabled = true

                if (column.propFormatter !== undefined && column.propFormatter !== null) {
                    const reg = /^function\(([^\)]*)\)\{([\s\S]*)\}$/
                    if (column.propFormatter.indexOf('component：') !== -1 || column.propFormatter.indexOf('component:') !== -1) {
                        column.propFormatter = column.propFormatter.replace('component:', ' component：')
                        this.componentColumn = this.$loadComponent(column.propFormatter.split('component：')[1])
                    } else if (column.propFormatter.indexOf('function：') !== -1) {
                        column.funcFormatter = this.$vnode.context[column.propFormatter.split('function：')[1]]
                    } else if (reg.test(column.propFormatter)) {
                        column.funcFormatter = new Function(column.propFormatter.replace(reg, '$1'), column.propFormatter.replace(reg, '$2'))
                    }
                } else {
                    column.propFormatter = ''
                }

                column.title = generateTitle(column, this)
            })
        },
        refreshListData() {
            this.initTbColumns()
            this.loadListdata()
        },
        async loadListdata(searchMap, searchAndOr, customBtnVal, moduleCode) {
            if (moduleCode && this.moduleInfo.moduleCode !== moduleCode) return

            this.emptyText = ''
            if (this.mode === 'design') return

            if (this.listdata.length > 0) {
                this.pageInfo.list = this.listdata
                return
            }
            if (typeof this.moduleInfo.listDataUrl === 'undefined') return

            if (this.loading === true) {
                return
            } else {
                this.loading = true

                if (this.loadingMast !== null) this.loadingMast.close()

                try {
                    this.loadingMast = this.$loading({
                        target: '.' + this.moduleClass + ' .el-table__body-wrapper'
                    })
                } catch (e) {
                    this.loadingMast = this.$loading({
                        target: '.data-table-container .el-table__body-wrapper'
                    })
                }
            }

            this.searchAndOr = searchAndOr || this.searchAndOr
            this.searchMap = searchMap || this.searchMap

            const orderBy = this.pageInfo.orderBy || this.moduleInfo.listDefaultOrderBy
            this.pageInfo.listpageId = this.moduleInfo.listpageId
            this.pageInfo.listpageViewUrl = this.moduleInfo.listpageViewUrl
            this.pageInfo.orderBy = orderBy
            this.pageInfo.searchAndOr = this.searchAndOr
            this.pageInfo.searchMap = this.searchMap

            customBtnVal = customBtnVal || this.customBtnVal

            if (this.mode === 'listpage' && this.$route.meta.params !== undefined && this.$route.meta.params !== null) {
                const params = this.$route.meta.params.split('&')
                const _this = this
                params.forEach(function(param) {
                    _this.pageInfo[param.split('=')[0]] = param.split('=')[1]
                    _this.$route.query[param.split('=')[0]] = param.split('=')[1]
                })
            }
            await this.onListDataBeforeLoad(this, this.pageInfo)

            if (this.moduleInfo.listpageViewUrl !== undefined && this.pageInfo.sysCode === undefined) {
                if (this.$route.meta && this.$route.meta.sysCode) {
                    this.pageInfo.sysCode = this.$route.meta.sysCode
                }
            }

            // 自定义toobar筛选值
            if (customBtnVal !== '' && customBtnVal !== null && customBtnVal !== undefined) {
                if (this.pageInfo.urlsearch !== null && this.pageInfo.urlsearch !== '' && this.pageInfo.urlsearch !== undefined) {
                    if (this.pageInfo.urlsearch.indexOf(customBtnVal.field) > -1) {
                        const s = this.pageInfo.urlsearch.split(';')
                        let search = ''
                        s.forEach(v => {
                            if (v.indexOf(customBtnVal.field) > -1) {
                                v = (customBtnVal.value !== '' ? (customBtnVal.field + ':' + customBtnVal.value) : '')
                            }
                            if (search !== '')search += ';'
                            search += (v !== '' ? v : '')
                        })
                        this.pageInfo.urlsearch = search
                    } else {
                        this.pageInfo.urlsearch += customBtnVal.value !== '' ? (';' + customBtnVal.field + ':' + customBtnVal.value) : ''
                    }
                } else {
                    this.pageInfo.urlsearch = customBtnVal.value !== '' ? (customBtnVal.field + ':' + customBtnVal.value) : ''
                }
            }

            const res = await this.$app.listdata(this.moduleInfo.listDataUrl, this.pageInfo)
            if (res.code === 'success') {
                this.pageInfo = res.body.pageInfo
                this.pageInfo.orderBy = orderBy
                this.pageInfo.passenger = res.body.passenger
                await this.onListDataLoaded(this, this.pageInfo)

                if (this.$route.meta && !this.moduleInfo.disableCache) {
                    const view = { fullPath: this.$route.fullPath, pageInfo: this.pageInfo, listDataUrl: this.moduleInfo.listDataUrl }
                    this.$store.dispatch('tagsView/updateVisitedView', view)
                }
                this.$nextTick(() => {
                    this.setScrollPosition()
                })
            } else {
                this.$alert(res.message, '操作提示', { type: 'error' })
            }

            this.$bus.emit('setTabFileCount')

            this.emptyText = '暂无数据'
            this.loadingMast.close()
            this.loading = false
            this.$nextTick(() => {
                this.setStyleSelectAll()
            })
        },
        handlePageSizeChange(val) {
            this.pageInfo.pageNum = 1
            this.pageInfo.pageSize = val
            this.loadListdata()
        },
        handlePageNumChange(val) {
            this.pageInfo.pageNum = val
            this.loadListdata()
        },
        // 翻页/改变分页时
        setScrollPosition() {
            let parent = this.$el.parentNode
            if (parent !== null) {
                while (parent !== null && parent.tagName !== 'BODY' && parent.className.indexOf('el-dialog') === -1) {
                    parent = parent.parentNode
                }
                if (parent !== null && parent.tagName === 'BODY') {
                    const element = document.querySelector('.main-container')
                    if (element !== null) {
                        const scrollDom = element.querySelector('.app-main .el-scrollbar .el-scrollbar__wrap')
                        if (scrollDom !== null)scrollDom.scrollTop = 0
                    }
                }
            }
        },
        handleSortChange({ column, prop, order }) {
            if (order === 'descending') {
                this.pageInfo.orderBy = prop + ' desc'
            } else if (order === 'ascending') {
                this.pageInfo.orderBy = prop + ' asc'
            } else {
                this.pageInfo.orderBy = this.moduleInfo.listDefaultOrderBy
            }
            this.loadListdata()
        },
        setStyleSelectAll() {
            if (this.mode === 'listpage' && this.maxSelectRow !== null) {
                const th = document.querySelector('.data-table-container .el-table__header .column_checkbox')
                const selectall = th !== null ? th.querySelector('.cell') : null
                if (selectall && !selectall.querySelector('.el-checkbox.is-disabled')) {
                    selectall.innerHTML = '<label class="el-checkbox is-disabled"><span class="el-checkbox__input is-disabled"><span class="el-checkbox__inner"></span><input type="checkbox" aria-hidden="false" disabled="disabled" class="el-checkbox__original" value=""></span></label>'
                }
            }
        },
        handleSelectChange(selection) {
            if (this.maxSelectRow !== null) {
                if (selection.length > this.maxSelectRow) {
                    this.$refs.listpageDataTable.toggleRowSelection(selection[0])
                }
                if (selection.length <= this.maxSelectRow) {
                    const copyselection = JSON.parse(JSON.stringify(selection))
                    this.selectedRows = copyselection.splice(0, copyselection.length - this.maxSelectRow)
                    this.onSelectedRowsChange(copyselection)
                }
            } else {
                this.selectedRows = selection
                this.onSelectedRowsChange(selection)
            }
        },
        handleCellClick(row, column, cell, event) {
            if (cell.className.indexOf('content-column') !== -1) {
                if (this.onCellClick !== null) {
                    this.onCellClick(row, column, cell.innerText, cell.cellIndex)
                } else {
                    this.$bus.emit('openBusiform', this.moduleInfo, row, 0)
                }
            }
        },
        setColumnEnabled(val) {
            this.tbColumns.forEach(column => {
                const enabledColums = val.join(',') + ','

                if (enabledColums.indexOf(column.field + ',') !== -1) {
                    column.enabled = true
                } else {
                    column.enabled = false
                }
            })
            this.$forceUpdate()
        },
        // 自定义按钮点击回调事件
        selectCustomToolbar(val) {
            if (this.customToolbarBtnsClick !== null && val.type === 'custom_btn') {
                this.customToolbarBtnsClick(val)
            } else {
                this.customBtnVal = val
                this.loadListdata(null, null, val)
            }
        },
        addObject() {
            this.innerTableBtnDisabled = true
            if (this.mode === 'inner' && this.$vnode.context.$vnode.context.vo.isnew) {
                this.$bus.emit('submitBusiform', this.$vnode.context.$vnode.context.moduleInfo, callBack => {
                    this.$nextTick(() => { this.innerTableBtnDisabled = false })
                    if (callBack) {
                        this.$bus.emit('openBusiform', this.moduleInfo, null, 1)
                    }
                }, 'InnerTableSave')
            } else if (this.mode === 'inner' && this.$vnode.context.$vnode.context.wfInstance && this.$vnode.context.$vnode.context.wfInstance.status === -1) {
                this.$parent.$parent.$vnode.context.btnSubmitClick('AutoSave', saveRst => {
                    this.$nextTick(() => { this.innerTableBtnDisabled = false })
                    if (saveRst) {
                        this.$bus.emit('openBusiform', this.moduleInfo, null, 1)
                    }
                }, 'InnerTableSave')
            } else {
                this.$nextTick(() => { this.innerTableBtnDisabled = false })
                this.$bus.emit('openBusiform', this.moduleInfo, null, 1)
            }
        },
        editObject(row, column, value, index) {
            this.$bus.emit('openBusiform', this.moduleInfo, row, 1)
        },
        deleteIds(row, column, value, index) {
            var ids = this.getSelectedRows(row, column, value, index)
            if (ids.length === 0) {
                this.$alert('请选择需要删除的数据。', '操作提示', { type: 'info' })
                return
            }
            this.$confirm('您是否确认删除选择的数据?', '确认操作', { type: 'warning' })
                .then(async() => {
                    const res = await this.$app.deleteByIds(this.moduleInfo.delUrl, ids)

                    if (res.code === 'success') {
                        this.onDeleteSuccessed(this, ids)

                        this.$message({ type: res.code, message: res.message, showClose: true })
                        this.loadListdata()
                    } else if (res.code === 'confirm') {
                        this.$confirm(res.message, '确认操作', { type: 'warning' })
                            .then(async() => {
                                const res = await this.$app.deleteByIds(this.moduleInfo.delUrl, ids, true)
                                if (res.code === 'success') {
                                    this.onDeleteSuccessed(this, ids)
                                    this.$message({ type: res.code, message: res.message, showClose: true })
                                    this.loadListdata()
                                } else {
                                    this.$alert(res.message, '操作提示', { type: 'error' })
                                }
                            }).catch(err => { if (err !== 'cancel') { console.error(err) } })
                    } else {
                        this.$alert(res.message, '操作提示', { type: 'error' })
                    }
                })
                .catch(err => { if (err !== 'cancel') { console.error(err) } })
        },
        getSelectedRows(row, column, value, index) {
            var ids = []
            if (typeof index === 'undefined') {
                this.selectedRows.forEach(function(row) {
                    ids.push(row.id)
                })
            } else {
                ids = [row.id]
            }
            return ids
        },
        // 控制行是否可被选中
        selectable(row, index) {
            let status = true
            if (this.cellSelectionStatus !== null && this.cellSelectionStatus !== undefined) {
                status = this.cellSelectionStatus(row, index)
            }
            return status
        },
        elementValueFormatter(row, column, value, index) {
            if (value == null) return value

            var newValue = value
            column = this.tbColumns.filter(item => {
                if (item.field === column.property) return true
            })[0]
            column.formatterMap = null
            var colFormater = column.propFormatter
            if (typeof colFormater === 'undefined' || colFormater === null || colFormater === '') colFormater = column.elementFormatter
            if (typeof colFormater === 'undefined' || colFormater === null) colFormater = ''

            if (column.propType === 'java.math.BigDecimal' || column.propType === 'Float') {
                value = Number(value).toFixed(2)
            }

            if (column.propType === 'java.util.Date' || (colFormater.toUpperCase().indexOf('YYYY') !== -1 && colFormater.toUpperCase().indexOf('MM') !== -1) || (colFormater.toUpperCase().indexOf('MM') !== -1 && colFormater.toUpperCase().indexOf('DD') !== -1)) {
                var format = colFormater.replace(/\r\n/g, '').replace(/\r/g, '').replace(/\n/g, '')
                if (format.indexOf('format：') === 0) {
                    format = format.substring(7)
                    const tDate = new Date(value.replace(/-/g, '/'))

                    if (!isNaN(tDate.getTime())) {
                        newValue = moment(new Date(value.replace(/-/g, '/'))).format(format.replace('yyyy', 'YYYY').replace('dd', 'DD'))
                    }
                }
            } else if (colFormater.indexOf('valueSuffix：') === 0) {
                newValue = value + colFormater.split('valueSuffix：')[1]
            } else {
                if (!column.formatterMap && (column.listAdvSearchElement === 'checkbox' || column.listAdvSearchElement === 'radio' || column.listAdvSearchElement === 'select')) {
                    if (this.pageInfo.passenger && typeof this.pageInfo.passenger[column.field + 'Options'] === 'object' && this.pageInfo.passenger[column.field + 'Options'].length > 0) {
                        column.formatterMap = {}
                        this.pageInfo.passenger[column.field + 'Options'].forEach(item => {
                            column.formatterMap[item.value] = item.text
                        })
                    }
                }

                const formatterMap = column.formatterMap || {}
                if (!column.formatterMap) {
                    column.formatterMap = {}
                    var formatters = colFormater.replace(/\r\n/g, '<br>').replace(/\\r\\n/g, '<br>').replace(/\n/g, '<br>').replace(/\\n/g, '<br>').split('<br>')
                    for (let i = 0; i < formatters.length; i++) {
                        if (formatters[i].split('：').length > 1) {
                            const v = formatters[i].split('：')[0]
                            formatterMap[v] = formatters[i].split('：')[1]
                        }
                    }
                    column.formatterMap = formatterMap
                }

                // 当字段为多选值时
                if (typeof value === 'string' && value.indexOf(',') > -1) {
                    newValue = ''
                    value.split(',').forEach(v => {
                        if (newValue !== '') {
                            newValue += '、'
                        }

                        let converted = false
                        for (const key in formatterMap) {
                            if (v === (key + '')) {
                                newValue += formatterMap[key]
                                converted = true
                                break
                            }
                        }
                        if (!converted) {
                            newValue += v
                        }
                    })
                }

                if (formatterMap[value]) {
                    newValue = formatterMap[value]
                } else if (column.propType === 'boolean') {
                    newValue = formatterMap[value ? 1 : 0]
                }
            }
            return newValue
        },
        setResPermission(resEntityName, permissionCode, roleFilter) {
            const ids = []
            let errMsg = ''
            let orgCode = null
            let sysCode = null
            this.selectedRows.forEach((row, index) => {
                orgCode = row.orgCode

                if (roleFilter === 'sysCode' || !row.orgCode) {
                    sysCode = row.sysCode || row.systemCode
                }

                if (index > 0 && row.orgCode && this.selectedRows[0].orgCode !== row.orgCode) {
                    errMsg = '只能设置同属一个机构的数据访问权限。'
                } if (index > 0 && row.sysCode && this.selectedRows[0].sysCode !== row.sysCode) {
                    errMsg = '只能设置同属一个产品的数据访问权限。'
                } else {
                    ids.push(row.id + '*' + (row.sysCode || row.systemCode) + '*' + (row.sysName || row.systemName))
                }
            })
            if (errMsg !== '') {
                this.$alert(errMsg, '操作提示', { type: 'warning' })
                return
            }
            if (ids.length === 0) {
                this.$alert('请选择需要设置访问权限的数据！', '操作提示', { type: 'warning' })
                return
            }

            this.showResPermission = true
            const _this = this
            this.$nextTick(() => {
                let visitType = 1
                if (this.selectedRows.length > 0) visitType = _this.selectedRows[0].visitType
                _this.$bus.emit('openResPermissionForm', ids, visitType, resEntityName, permissionCode, orgCode, sysCode)
            })
        },
        /**
		 * 批量导出数据项SQL脚本文件
		 */
        exportData(tbName) {
            var ids = this.getSelectedRows()
            if (ids.length === 0) {
                this.$alert('请选择需要导出的数据！', '操作提示', { type: 'info' })
                return
            }

            const dialectList = []
            dialectList.push({ 'text': 'MySql', 'value': 'mysql' })
            dialectList.push({ 'text': 'SqlServer', 'value': 'sqlserver' })
            dialectList.push({ 'text': 'Oracle', 'value': 'oracle' })
            dialectList.push({ 'text': 'GBase', 'value': 'gbase' })

            this.$bus.emit('openListitemDialog', '目标数据库', dialectList, rst => {
                if (rst.code === 'success') {
                    this.$http({
                        method: 'post',
                        params: { 'ids': ids.join(), 'tbName': tbName, 'dialect': rst.value },
                        url: 'base/codeGenerate/exportDataItemDbSql'
                    }).then(res => {
                        if (res.code === 'success') {
                            this.loadListdata()

                            const downloadUrl = '<br/>下载代码：<a href="' + process.env.VUE_APP_BASE_API + '/' + encodeURI(res.body.zipurl) + '" target="_blank">' + res.body.zipname + '</a>'
                            this.$alert(res.message + downloadUrl, '操作提示', { type: 'success', dangerouslyUseHTMLString: true })
                        } else {
                            this.$alert(res.message, '操作提示', { type: 'error' })
                        }
                    })
                }
            }, null, null, '请选择目标数据库类型：')
        },
        /**
		* 批量导出流程表单EXCEL文件
		*/
        async exportWform(filename) {
            var ids = this.getSelectedRows()
            new Promise((resolve, reject) => {
                if (this.pageInfo.total === 0) {
                    this.$alert(this.emptyText, '操作提示', { type: 'warning' })
                    reject(this.emptyText)
                }

                if (ids.length === 0) {
                    this.$confirm('您是否确认要导出当前列表的全部数据?<br/>如果仅需导出部分数据，请先选择或通过搜索筛选。', '确认操作', { type: 'warning', dangerouslyUseHTMLString: true })
                        .then((res) => {
                            resolve(true)
                        })
                        .catch(err => {
                            if (err !== 'cancel') {
                                console.error(err)
                                reject(err)
                            }
                        })
                } else {
                    resolve(true)
                }
            }).then(async result => {
                let reqParams = { pageSize: 65000, pageNum: 1 }

                const orderBy = this.pageInfo.orderBy || this.moduleInfo.listDefaultOrderBy
                reqParams.listpageId = this.moduleInfo.listpageId
                reqParams.listpageViewUrl = this.moduleInfo.listpageViewUrl
                reqParams.orderBy = orderBy
                reqParams.searchAndOr = this.searchAndOr
                reqParams.searchMap = this.searchMap

                if (this.mode === 'listpage' && this.$route.meta.params !== undefined && this.$route.meta.params !== null) {
                    const params = this.$route.meta.params.split('&')
                    params.forEach(function(param) {
                        reqParams[param.split('=')[0]] = param.split('=')[1]
                    })
                }
                await this.onListDataBeforeLoad(this, reqParams)

                if (ids.length > 0) {
                    if (reqParams.urlsearch) {
                        reqParams.urlsearch += ';id in ' + ids.join(',')
                    } else {
                        reqParams.urlsearch = 'id in ' + ids.join(',')
                    }
                }

                reqParams = qs.stringify(reqParams)

                let url = process.env.VUE_APP_BASE_API + '/' + this.moduleInfo.listDataUrl.replace('listdata', 'exportdata').replace('listWfInstance', 'exportWfInstance').replace('joinListdata', 'joinExportdata')
                if (this.moduleInfo.exportDataUrl) {
                    url = this.moduleInfo.exportDataUrl
                }
                if (url.indexOf('?') === -1) {
                    url += '?' + reqParams
                } else {
                    url += '&' + reqParams
                }

                let fileName = filename
                if (!fileName) {
                    fileName = document.querySelector('#breadcrumb-container').innerText.replace('\r\n', '-').replace('\r', '-').replace('\n', '-')
                    if (this.$route.meta.level === 4) {
                        fileName += '-' + this.$route.meta.title
                    }
                }
                url += '&fileName=' + encodeURI(encodeURI(fileName)) + '&httpPort=' + location.port
                window.open(url)
            })
        },
        batchSaveFiles() {
            var ids = this.getSelectedRows()
            if (ids.length === 0) {
                this.$alert('请选择需要批量下载的数据。', '操作提示', { type: 'info' })
                return
            }

            this.$bus.emit('showDoingDialog')

            const url = this.moduleInfo.listDataUrl.split('/')[0] + '/webForm/batchDownload'
            this.$http({
                method: 'post',
                params: { 'busiDataIds': ids.join(), 'module': this.moduleInfo.listDataUrl.split('/')[1] },
                url: url
            }).then(res => {
                this.$bus.emit('closeDoingDialog')

                if (res.code === 'success') {
                    this.loadListdata()

                    const downloadUrl = '<br/>下载文件：<a href="' + process.env.VUE_APP_BASE_API + '/' + encodeURI(res.body.zipurl) + '" target="_blank">' + res.body.zipname + '</a>'
                    this.$alert(res.message + downloadUrl, '操作提示', { type: 'success', dangerouslyUseHTMLString: true })
                } else {
                    this.$alert(res.message, '操作提示', { type: 'error' })
                }
            })
        },
        decryptData(row, model) {
            this.$app.decryptData(row[model]).then(res => {
                if (res.code === 'success') {
                    this.$set(row, model, res.body.data)
                } else {
                    this.$alert(res.message, { type: 'error' })
                }
            })
        }
    }
}
</script>

<style lang="scss" scoped>
    .content-column {
        cursor: pointer;
    }
    .column_operate{
        white-space:nowrap!important;
        overflow:hidden!important;
        word-break:keep-all;

       /deep/ .cell{
        white-space:nowrap!important;
        overflow:hidden!important;
        word-break:keep-all;
        }

    }
    .el-pagination-container{
        text-align:right;
        margin-top:20px;
        }
    .el-pagination{
        padding-right:0;
        font-weight:normal;
        /* color:#409eff; */
     }
    .el-icon::before {
        padding-right: 3px;
    }

    /deep/  th>.cell{
        word-break: keep-all;
        white-space: nowrap
    }
</style>
